use std::process;
use rsminigrep::Config;
fn main() {
    // 接收形如 IGNORE_CASE=1 cargo run -- searchstring filename.txt 的命令行参数
    // cargo run -- diminished /codelocal/langrust/rsminigrep/src/interview.txt
    // IGNORE_CASE=1 cargo run -- DIMINISHED /codelocal/langrust/rsminigrep/src/interview.txt
    
    // 将环境变量中的命令行参数收集起来
    // 因为 collect 方法不知道收集到的目标对象是数组还是哈希表，所以我们必须明确指定args的类型，因为编译器无法自行推断
    let args: Vec<String> = std::env::args().collect();
    //dbg!(args); // 调试打印显示有三个参数，包括当前二进制文件名 ["target/debug/rsminigrep", "searchstring", "filename.txt"]

    // 注意parse_config接收的是数组切片，所以不会发生所有权的转移。
    //let (query,file_path) = parse_config(&args);
    //println!("searching for {}", query);
    //println!("in file {}", file_path);
    // 
    // 以上为过程变成，转为面向对象的模式
    // let config = Config::new(&args);

    // 鉴于new方法使用panic处理的暴力特征，我们改为带错误处理的方式
    // 处理错误使用 unwrap_or_else 这种闭包动态处理，而不是 unwrap_or 这种默认值处理
    let config = Config::build(&args).unwrap_or_else(|err|{
        eprintln!("Parsing arguments error: {err}"); // 错误信息输出到 标准错误输出中 
        process::exit(1); // 理论上应该返回 Config 类型，但是因为没什么好处理的，直接exit得了...
    });

    // 使用 if let 这种模式匹配的方法去匹配枚举中的指定枚举类型
    // 因为我们不关心Ok类型，只需要匹配Err类型就好了
    if let Err(e) = rsminigrep::run_e(config) {
        eprintln!("Application error: {e}"); // 错误信息输出到 标准错误输出中 
        process::exit(1);
    }
    
}
